/*
 *  Test.cpp
 *  
 *
 *  Created by Daniel Condon on 22/08/12.
 *  Copyright 2012 __MyCompanyName__. All rights reserved.
 *
 */

#include <GLUT/glut.h>
#include <OpenGL/glu.h>
#include <OpenGL/gl.h>
#include <OpenGL/OpenGL.h>

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <math.h>

#include "IBMController.h"
#include "Quadtree.h"

using namespace std;

const int VIEW_DISTANCE = 100;
const int WINDOW_SIZE_X = 600;
const int WINDOW_SIZE_Y = 600;

const int creatureSize = 5.0;

IBMController* IBMMonitor;

bool DEBUG, paused;

void convertMouseCoord(int x, int y){
	//mouseXObjectSpace = (x - (WINDOW_SIZE_X/2.0f)) / (WINDOW_SIZE_X/2.0f) * (VIEW_DISTANCE/2.0f);
	//mouseYObjectSpace = (-y + (WINDOW_SIZE_Y/2.0f)) / (WINDOW_SIZE_Y/2.0f) * (VIEW_DISTANCE/2.0f);
}

void Init(){
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glClear(GL_COLOR_BUFFER_BIT);
	glEnable(GL_CULL_FACE);
	glEnable (GL_BLEND);
	glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}

void DrawActiveQuadtrees(){
	
}

void DrawDetectCircle(double X, double Y, int size){
	glBegin(GL_LINE_LOOP);
	for (unsigned int angle = 0; angle < 360; angle+=5) {
		float deg = angle*3.1415/180;
		glVertex2f(X + sin(deg) * size, Y + cos(deg) * size);
	}
	glEnd();
}

void Draw2DCreatures(){
	for (int i = 0; i < IBMMonitor->getNumCreatures(); i++) {
		Brain* cb = IBMMonitor->getCreature(i);
		if (DEBUG) {
			vector<Brain*> joins = cb->connected();
			glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
			for (int b = 0; b < joins.size(); b++) {
				glBegin(GL_LINES);
				glVertex2f(cb->getPos().getX(), cb->getPos().getY());
				glVertex2f(joins.at(b)->getPos().getX(), joins.at(b)->getPos().getY());
				glEnd();
			}
			
			//draw detect circles
			glColor4f(0.0f, 1.0f, 0.0f, 0.5f);
			DrawDetectCircle(cb->getPos().getX(), cb->getPos().getY(), 40.0);
		}
		switch (cb->infectionStatus()) {
			case 0:
				glColor4f(1.0f,1.0f,1.0f,1.0f);
				break;
			case 1:
				glColor4f(0.0f, 0.8f, 0.2f, 1.0f);
				break;
			case 2:
				glColor4f(0.6f, 0.4f, 0.0f, 1.0f);
				break;
			default:
				glColor4f(1.0f, 1.0f ,1.0f ,1.0f);
				break;
		}
		glBegin(GL_LINE_LOOP);
		glVertex2f(cb->getPos().getX()-creatureSize, cb->getPos().getY()+creatureSize);
		glVertex2f(cb->getPos().getX()+creatureSize, cb->getPos().getY()+creatureSize);
		glVertex2f(cb->getPos().getX()+creatureSize, cb->getPos().getY()-creatureSize);
		glVertex2f(cb->getPos().getX()-creatureSize, cb->getPos().getY()-creatureSize);
		glEnd();
	}
}

void display(){
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(-VIEW_DISTANCE, VIEW_DISTANCE, -VIEW_DISTANCE, VIEW_DISTANCE);
	//glOrtho(-VIEW_DISTANCE, VIEW_DISTANCE, -VIEW_DISTANCE, VIEW_DISTANCE, -VIEW_DISTANCE, VIEW_DISTANCE);	
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glClear(GL_COLOR_BUFFER_BIT);
	
	Draw2DCreatures();
	DrawActiveQuadtrees();
	
	glutSwapBuffers();
}

void reshape(int w, int h){
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(-VIEW_DISTANCE, VIEW_DISTANCE, -VIEW_DISTANCE, VIEW_DISTANCE);
	//glOrtho(-VIEW_DISTANCE, VIEW_DISTANCE, -VIEW_DISTANCE, VIEW_DISTANCE, -VIEW_DISTANCE, VIEW_DISTANCE);
	glutPostRedisplay();
}

void KeyboardController(GLubyte key, GLint x, GLint y){
	switch ((char)key) {
		case 27:
			exit(1);
			break;
		case 'd':
			DEBUG = !DEBUG;
			break;
		case 'i':
			IBMMonitor->getCreature(0)->giveVirus();
			break;
		case ' ':
			paused = !paused;
			break;
		default:
			break;
	}
}

void mouseInput(int button, int state, int x, int y){
	convertMouseCoord(x, y);
	//int clickX, clickY;
	//clickX = (mouseXObjectSpace);
	//clickY = (mouseYObjectSpace);
	//cout << clickX << ":" << clickY << endl;
}

void LogicLoop(int value){
	if (!paused) {
		IBMMonitor->Cycle();
		glutPostRedisplay();
	}
	glutTimerFunc(value, LogicLoop, value);
}

void SafeClose(){
	delete IBMMonitor;
}

int main(int argc, char** argv){
	srand(time(NULL));
	IBMMonitor = new IBMController(10);
	DEBUG = false;
	glutInitWindowSize(WINDOW_SIZE_X, WINDOW_SIZE_Y);
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
	glutCreateWindow("IBM Tester");
	
	Init();
	glutKeyboardFunc(KeyboardController);
	glutDisplayFunc(display);
	glutReshapeFunc(reshape);
	glutMouseFunc(mouseInput);
	
	LogicLoop(15);
	glutMainLoop();
	
	SafeClose();
	return 0;
}

